import shareService from "../service/share.service.js";
import fileService from "../service/file.service.js";
import "express-async-errors";
import path from "path";
import fse from "fs-extra";
import jwt from "jsonwebtoken";
import fileController from "./file.controller.js";
import downloadService from "../service/download.service.js";

const UPLOADS_DIR = path.resolve("uploads", "files");

const createShare = async (req, res) => {
  const userId = req.user.id;
  const { fileId, pwd, expires } = req.body;

  const file = await fileService.getFileById(fileId);
  if (!file || file.isDeleted || file.userId !== userId) {
    return res.status(404).json({ message: "文件不存在或不是你的文件" });
  }

  const share = await shareService.getShareByFileId(fileId, userId);
  if (share) {
    await shareService.updateShare(share.id, { pwd, expires });
    return res.status(201).json({ message: "已重新分享" });
  }

  const data = await shareService.createShare(userId, fileId, pwd, expires);
  res.status(201).json({ message: "分享成功", data });
};

const verifyShare = async (req, res) => {
  const shareId = req.params.shareId;
  const pwd = req.body.pwd;

  const share = await shareService.getShareById(shareId);
  if (!share || share.file.isDeleted) {
    return res.status(404).json({ message: "分享文件不存在" });
  }

  if (share.expires && new Date(share.expires) < new Date()) {
    return res.status(403).json({ message: "分享文件已过期" });
  }

  if (share.pwd && pwd !== share.pwd) {
    return res.status(403).json({ message: "密码错误" });
  }

  return res.status(200).json({ message: "验证成功", data: share.file });
};

const deleteShare = async (req, res) => {
  const shareId = req.params.shareId;
  const userId = req.user.id;

  const share = await shareService.getShareById(shareId);
  if (!share || share.userId !== userId) {
    return res.status(404).json({ message: "分享链接不存在" });
  }

  await shareService.deleteShare(shareId);
  return res.status(204).json({ message: "删除成功" });
};

const deleteShares = async (req, res) => {
  const shareIds = req.body.shareIds;

  await shareService.deleteShares(shareIds);
  return res.status(204).json({ message: "删除成功" });
};

const getShares = async (req, res) => {
  const userId = req.user.id;
  const shares = await shareService.getUserShares(userId);
  return res.status(200).json({ message: '获取成功', data: shares });
};

const getShareById = async (req, res) => {
  const shareId = req.params.shareId;
  const share = await shareService.getShareById(shareId);
  share.haspwd = share.pwd ? true : false;
  if (!share) {
    return res.status(404).json({ message: "分享链接不存在" });
  } else {
    return res.status(200).json({ data: share });
  }
};

//直接下载分享
const downloadShare = async (req, res) => {
  const shareId = req.params.shareId;
  const pwd = req.body.pwd;

  const share = await shareService.getShareById(shareId);
  if (!share || share.file.isDeleted) {
    return res.status(404).json({ message: "分享文件不存在" });
  }

  if (share.expires && new Date(share.expires) < new Date()) {
    return res.status(403).json({ message: "分享文件已过期" });
  }

  if (share.pwd && pwd !== share.pwd) {
    return res.status(403).json({ message: "密码错误" });
  }

  const file = share.file;

  const ext = path.extname(file.filename).toLowerCase();
  const fileName = file.hash + ext;
  const filePath = path.resolve(UPLOADS_DIR, fileName);

  await downloadService.createDownload(file.id, req.ip, req.get('User-Agent'));

  console.log("直接下载分享", filePath);
  res.setHeader(
    "Content-Disposition",
    `attachment; filename="${encodeURIComponent(file.filename)}"`,
  );
  res.setHeader("Content-Type", file.type);

  const fileStream = fse.createReadStream(filePath);
  fileStream.pipe(res);

  fileStream.on("error", (err) => {
    console.error("下载错误:", err);
    res.status(500).json({ message: "文件下载失败" });
  });
}

// 生成带签名的下载直链 由浏览器直接下载 避免权限验证
const getShareUrl = async (req, res) => {
  const shareId = req.params.shareId;
  const pwd = req.body.pwd;

  console.log("获取分享下载链接", shareId, pwd);
  const share = await shareService.getShareById(shareId);
  if (!share || share.file.isDeleted) {
    return res.status(404).json({ message: "分享文件不存在" });
  }

  if (share.expires && new Date(share.expires) < new Date()) {
    return res.status(403).json({ message: "分享文件已过期" });
  }

  if (share.pwd && pwd !== share.pwd) {
    return res.status(403).json({ message: "密码错误" });
  }


  if (share.file.isFolder) {
    const { signature, success, message } = await fileController.archiveFolder(share.fileId, share.userId);
    if (!success) {
      return res.status(400).json({ message });
    }
    return res.json({ signature });
  }

  const signature = jwt.sign(
    { hash: share.file.hash, filename: share.file.filename, type: share.file.type, isArchive: share.file.isFolder },
    process.env.JWT_SECRET,
    { expiresIn: process.env.URL_EXPIRES_IN },
  );
  await downloadService.createDownload(share.file.id, req.ip, req.get('User-Agent'));

  res.json({ signature });
};

const saveShare = async (req, res) => {
  const parentId = req.body.parentId ?? null;
  const shareId = req.params.shareId;
  const pwd = req.body.pwd;
  const userId = req.user.id;

  const share = await shareService.getShareById(shareId);
  if (!share || share.file.isDeleted) {
    return res.status(404).json({ message: "分享文件不存在" });
  }
  if (share.userId == userId) {
    return res.status(403).json({ message: "不能保存自己的分享" });
  }
  if (share.expires && new Date(share.expires) < new Date()) {
    return res.status(403).json({ message: "分享文件已过期" });
  }
  if (share.pwd && pwd !== share.pwd) {
    return res.status(403).json({ message: "密码错误" });
  }

  const { message, success } = await fileController.copyDo(share.fileId, parentId, userId, share.file.userId, share.file.filename);
  if (!success) {
    return res.status(400).json({ message });
  }
  res.json({ message: "保存成功" });
}

export default {
  createShare,
  verifyShare,
  deleteShare,
  getShares,
  getShareById,
  deleteShares,
  downloadShare,
  getShareUrl,
  saveShare
};
